﻿
using Mono.Cecil;

public class LuaTypeContext
{
    private readonly LuaModuleDefinition _module;
    private readonly LuaTypeDefinition _definition;
    private IDictionary<string, LuaMethodReference> _methodReferences;
    private IDictionary<string, LuaFieldReference> _fieldReferences;
    public ObjectKind StackType => _definition.StackType;
    public LuaMethodDefinition CurMethod { get; set; }
    public LuaTypeContext(LuaModuleDefinition module, LuaTypeDefinition definition)
    {
        _module = module;
        _definition = definition;
        _methodReferences = new Dictionary<string, LuaMethodReference>();
        _fieldReferences = new Dictionary<string, LuaFieldReference>();

    }
    internal LuaMethodReference GetMethodReference(LuaTypeReference type, MethodReference method)
    {
        var fullname = $"{type.FullName}.{method.Name}";
        if (_methodReferences.TryGetValue(fullname, out var luaMethod))
            return luaMethod;
        if (_definition == type)
            luaMethod = _definition.GetMethod(method);
        else if (type is LuaTypeDefinition definition)
            luaMethod = definition.GetMethod(method);
        else
            _methodReferences[fullname] = luaMethod = new LuaMethodReference(_module, method);
        return luaMethod;
    }
    internal LuaFieldReference GetFieldReference(FieldReference field)
        => GetFieldReference(GetTypeReference(field.Resolve().DeclaringType), field);

    internal LuaFieldReference GetFieldReference(LuaTypeReference type, FieldReference field)
    {
        var fullname = $"{type.FullName}.{field.Name}";
        if (_fieldReferences.TryGetValue(fullname, out var luaField))
            return luaField;
        if (_definition == type)
            luaField = _definition.GetField(field);
        else if (type is LuaTypeDefinition definition)
            luaField = definition.GetField(field);
        else
            _fieldReferences[fullname] = luaField = new LuaFieldReference(_module, field);
        return luaField;
    }
    internal LuaTypeReference GetTypeReference(TypeReference type)
    {
        return _module.GetTypeReference(type);
    }
}
